<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div id="app">
      <div>
        <span>姓名:</span>
        <input type="text" v-model.trim="student.name" />
      </div>
      <div>
        <span>年龄:</span>
        <input type="number" v-model.trim.number="student.age" @keyup.enter="addOrEdit" />
      </div>
      <div>
        <span>性别:</span>
        <select v-model="student.gender">
          <option value="男">男</option>
          <option value="女">女</option>
        </select>
      </div>
      <div>
        <button @click="addOrEdit">添加/修改</button>
      </div>
      <div>
        <table border="1" cellpadding="10" cellspacing="0">
          <tr>
            <th>序号</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>性别</th>
            <th>操作</th>
          </tr>
          <tr v-for="v, i of list">
            <td>{{ i + 1 }}</td>
            <td>{{ v.name }}</td>
            <td>{{ v.age }}</td>
            <td>{{ v.gender }}</td>
            <td>
              <button @click="del(i)">删除</button>
              <!-- 不能直接将 v 赋值给 student -->
              <!-- 因为 student 在上面 input 上是用 v-model 绑定的 -->
              <!-- 所以，在输入框中更新的时候，list 也会变，不符合案例需求（点击按钮 list 才变） -->
              <!-- 做一层深拷贝，搞出一个新的对象，这样 student 就不再是 list 中的对象了，而是一个新对象了 -->
              <button @click="goEdit(v)">编辑</button>
            </td>
          </tr>
        </table>
      </div>
  </div>
  <script src="./vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {

        // name: '',
        // age: '',
        // gender: '男',
        // 上面的三个数据太零散了，直接整合到一个对象中，表示一个学生信息
        student: {
          name: '',
          age: '',
          gender: '男',
        },

        list: [
          { id: 1, name: '张三', age: 18, gender: '男' },
          { id: 2, name: '李四', age: 19, gender: '女' },
        ]
      },
      methods: {
        del(i) {
          this.list.splice(i, 1)
        },
        goEdit(v) {
          // 如何一行代码实现深拷贝？
          // 1. JSON.stringify(obj) => JSON格式的字符串
          // 2. JSON.parse( (1)的结果 ) => 基于JSON格式的字符串转成对象了
          this.student = JSON.parse(JSON.stringify(v))
        },
        // student 在添加时，是没有 id 的，在修改时是有 id 的
        // 所以，可以根据 student 对象中当前是否有 id 来判断是添加还是编辑
        addOrEdit() {

          // 这个数据非法校验 不管是添加还是修改 都要做
          if (!this.student.name || !this.student.age) {
            return alert('数据不完整')
          }

          // 如果能走到这里，说明数据校验通过

          // 有 id，是编辑
          if (this.student.id) {
            // this.student 是 循环项 v，v 是 list 中循环出来的一个个对象，那么，this.student 就是 list 中的对象
            // 既然 student 是 list 中的对象，那么 student 本身就是响应式的，所以，直接修改 student，list 就变了
            
            // 编辑逻辑：
            // 1. 找出 student 在 list 中的索引（根据 id 找）（注意：id 和 索引 是两个不同的东西，不能混用）
            // 2. 用 this.student 去替换 list 中的
            // 2.1 先删除
            // 2.2 再添加新的

            const i = this.list.findIndex(v => v.id === this.student.id)
            this.list.splice(i, 1, this.student)
          }
          // 没 id，是添加 
          else {
            // 在添加进数组之前，需要给 student 加一个 id 属性
            this.student.id = Math.max(0, ...this.list.map(v => v.id)) + 1

            this.list.push(this.student)
          }

          // 表单重置，不管是添加 还是修改 都要做
          this.student = {
            name: '',
            age: '',
            gender: '男',
          }
          
        }
      }
    })
  </script>
</body>

</html>